home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Sample Controls / Shapes / CShapesControl.cpp next >
Encoding:
Text File  |  1996-12-17  |  7.9 KB  |  321 lines  |  [TEXT/CWIE]

  1. // =================================================================================
  2. //
  3. //    CShapesControl.cpp                ©1996 Microsoft Corporation All rights reserved.
  4. //
  5. // =================================================================================
  6.  
  7. #include "ocheaders.h"
  8. #include <math.h>
  9. #include "CShapesControl.h"
  10.  
  11. const Int32        DefaultIdleTicks    = 60;
  12. const Uint32    DefaultIdleRefCon    = 0;
  13.  
  14.  
  15. #pragma mark === CShapesControl::Construction & Destruction ===
  16.  
  17.  
  18. //=--------------------------------------------------------------------------=
  19. //  CShapesControl::CShapesControl    
  20. //=--------------------------------------------------------------------------=
  21.  
  22. CShapesControl::CShapesControl(void)
  23. {
  24.     mCurrentShape = ShapeType(BeginShapeType + 1);
  25.     mIsIdling = false;
  26.     mIsPressed = false;
  27. }
  28.  
  29.  
  30. //=--------------------------------------------------------------------------=
  31. //  CShapesControl::~CShapesControl
  32. //=--------------------------------------------------------------------------=
  33.  
  34. CShapesControl::~CShapesControl()
  35. {
  36. }
  37.  
  38. #pragma mark === CShapesControl::IControl Interface ===
  39.  
  40.  
  41. //=--------------------------------------------------------------------------=
  42. //  CShapesControl::IControl::Draw
  43. //=--------------------------------------------------------------------------=
  44.  
  45. STDMETHODIMP
  46. CShapesControl::Draw(DrawContext* inContext)
  47. {
  48.     if (inContext->DrawAspect != DVASPECT_CONTENT)
  49.         return DV_E_DVASPECT;
  50.  
  51.     //    we are in a context aspect, be sure we are idling
  52.     StartIdling();
  53.     DrawMe(&inContext->Location);
  54.     
  55.     return S_OK;
  56. }
  57.  
  58.  
  59. //=--------------------------------------------------------------------------=
  60. //  CShapesControl::IControl::GetUsedArea
  61. //=--------------------------------------------------------------------------=
  62.  
  63. STDMETHODIMP
  64. CShapesControl::GetUsedArea(PlatformRegion* outUsedArea)
  65. {
  66.     if (!outUsedArea->Region)
  67.         return E_FAIL;
  68.  
  69.     Rect        Bounds;
  70.  
  71.     Bounds.top = Bounds.left = 0;
  72.     Bounds.bottom = mSize.v;
  73.     Bounds.right = mSize.h;
  74.  
  75.     ::OpenRgn();
  76.     switch (mCurrentShape)
  77.     {
  78.         case OvalShapeType:
  79.             ::FrameOval(&Bounds);
  80.             break;
  81.         case TriangleShapeType:
  82.             ::MoveTo(mSize.h/3, 0);
  83.             ::LineTo(0, mSize.v/2);
  84.             ::LineTo(2*mSize.h/3, mSize.v);
  85.             ::LineTo(mSize.h/3, 0);
  86.             break;
  87.         case PentagonShapeType:
  88.             ::MoveTo(mSize.h/2, 0);
  89.             ::LineTo(0, mSize.v/3);
  90.             ::LineTo(mSize.h/3, mSize.v);
  91.             ::LineTo(2*mSize.h/3, mSize.v);
  92.             ::LineTo(mSize.h, mSize.v/3);
  93.             ::LineTo(mSize.h/2, 0);
  94.             break;
  95.         case HexagonShapeType:
  96.             ::MoveTo(mSize.h/2, 0);
  97.             ::LineTo(0, mSize.v/3);
  98.             ::LineTo(0, 2*mSize.v/3);
  99.             ::LineTo(mSize.h/2, mSize.v);
  100.             ::LineTo(mSize.h, 2*mSize.v/3);
  101.             ::LineTo(mSize.h, mSize.v/3);
  102.             ::LineTo(mSize.h/2, 0);
  103.             break;
  104.         case RectangleShapeType:
  105.         default:
  106.             ::FrameRect(&Bounds);
  107.             break;
  108.     }
  109.  
  110.     ::CloseRgn(outUsedArea->Region);
  111.     return S_OK;
  112. }
  113.  
  114.  
  115. //=--------------------------------------------------------------------------=
  116. //  CShapesControl::IControl::DoMouse    
  117. //=--------------------------------------------------------------------------=
  118.  
  119. STDMETHODIMP
  120. CShapesControl::DoMouse(MouseEventType inMouseET, PlatformEvent* inEvent)
  121. {
  122. #pragma unused (inEvent)
  123.     ErrorCode    theResult = S_FALSE;
  124.  
  125.     switch (inMouseET)
  126.     {
  127.         case MouseUp:
  128.             mIsPressed = false;
  129.             DrawAllContexts();
  130.             theResult = S_OK;
  131.             break;
  132.  
  133.         case MouseDown:
  134.           mIsPressed = true;
  135.           DrawAllContexts();
  136.           theResult = S_OK;
  137.           break;
  138.     }
  139.     
  140.     return theResult;
  141. }
  142.  
  143.  
  144. //=--------------------------------------------------------------------------=
  145. //  CShapesControl::IControl::DoIdle    
  146. //=--------------------------------------------------------------------------=
  147.  
  148. STDMETHODIMP
  149. CShapesControl::DoIdle(Uint32 IdleRefCon)
  150. {
  151. #pragma unused(IdleRefCon)
  152.     ShapeType    PrevShape = mCurrentShape;
  153.  
  154.     mCurrentShape = ShapeType(mCurrentShape + 1);
  155.     if (mCurrentShape >= EndShapeType)
  156.         mCurrentShape = ShapeType(BeginShapeType + 1);
  157.  
  158.     if (PrevShape != mCurrentShape)
  159.         mContainerSiteP->OnChange(UsedAreaChange);
  160.  
  161.     DrawAllContexts();
  162.  
  163.     return S_OK;
  164. }
  165.  
  166.  
  167. #pragma mark === CShapesControl::IPersist ===
  168.  
  169. //=--------------------------------------------------------------------------=
  170. //    CShapesControl::IPersistPropertyBag::IPersistPropertyBag::Load
  171. //=--------------------------------------------------------------------------=
  172.  
  173. STDMETHODIMP
  174. CShapesControl::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
  175. {
  176.     ErrorCode    ErrCode = S_OK;
  177.  
  178.     LoadTextState(PropertyBag, ErrorLog);
  179.     
  180.     return ErrCode;
  181. }
  182.  
  183. //=--------------------------------------------------------------------------=
  184. // CShapesControl::IPersistPropertyBag::LoadTextState
  185. //=--------------------------------------------------------------------------=
  186. // load in our text state for this control.
  187. //
  188. // Parameters:
  189. //    IPropertyBag *        - [in] property bag to read from
  190. //    IErrorLog *            - [in] errorlog object to use with proeprty bag
  191. //
  192. // Output:
  193. //    ErrorCode
  194. //
  195. STDMETHODIMP
  196. CShapesControl::LoadTextState(IPropertyBag *PropertyBag,IErrorLog *ErrorLog)
  197. {
  198.     ErrorCode    ECode = S_OK;
  199.     Int32        i;
  200.     VARIANT        v;
  201.  
  202.     v.vt = VT_BSTR;
  203.     v.bstrVal = NULL;
  204.  
  205.     //    get the starting size
  206.     if (PropertyBag->Read("width", &v, ErrorLog) == S_OK && v.bstrVal)
  207.     {
  208.         ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
  209.         mSize.h = i;
  210.         CoTaskMemFree(v.bstrVal);
  211.     }
  212.  
  213.     if (PropertyBag->Read("height", &v, ErrorLog) == S_OK && v.bstrVal)
  214.     {
  215.         ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
  216.         mSize.v = i;
  217.         CoTaskMemFree(v.bstrVal);
  218.     }
  219.  
  220.     return ECode;
  221. }
  222.  
  223.  
  224. #pragma mark === CShapesControl::protected methods ===
  225.  
  226. //=--------------------------------------------------------------------------=
  227. //  CShapesControl::StartIdling    
  228. //=--------------------------------------------------------------------------=
  229.  
  230. Boolean8
  231. CShapesControl::StartIdling(void)
  232. {
  233.     if (!mIsIdling)
  234.         mIsIdling = mContainerSiteP->SetIdleTime(DefaultIdleTicks, DefaultIdleRefCon) == S_OK;
  235.  
  236.     return mIsIdling;
  237. }
  238.  
  239.  
  240. //=--------------------------------------------------------------------------=
  241. //  CShapesControl::StopIdling    
  242. //=--------------------------------------------------------------------------=
  243.  
  244. Boolean8
  245. CShapesControl::StopIdling(void)
  246. {
  247.     if (mIsIdling && mContainerSiteP->SetIdleTime(RemoveAllIdlers, NULL) == S_OK)
  248.         mIsIdling = false;
  249.  
  250.     return !mIsIdling;
  251. }
  252.  
  253.  
  254. #pragma mark === CShapesControl::private methods ===
  255.  
  256. //=--------------------------------------------------------------------------=
  257. //  CShapesControl::DrawAllContexts    
  258. //=--------------------------------------------------------------------------=
  259.  
  260. void
  261. CShapesControl::DrawAllContexts()
  262. {
  263.     Boolean8        ShouldBeIdling = false;
  264.     Int32            Index = 1;
  265.     DrawContext        Context = {BeginPortType};
  266.     UInt32            ContextID;
  267.  
  268.     while ( GetContextID(Index, &ContextID) )
  269.     {
  270.         if (mContainerSiteP->AcquireContext(ContextID, &Context) == S_OK)
  271.         {
  272.             //    we could do this by watching context changes, but this is a simple
  273.             //    control which ignores such things - so instead we'll just watch this way
  274.             if (Context.DrawAspect == DVASPECT_CONTENT)
  275.                 ShouldBeIdling = true;
  276.             DrawMe(&Context.Location);
  277.             mContainerSiteP->ReleaseContext(&Context);
  278.         }
  279.         ++Index;
  280.     }
  281.  
  282.     if (ShouldBeIdling != mIsIdling)
  283.     {
  284.         if (ShouldBeIdling)
  285.             StartIdling();
  286.         else
  287.             StopIdling();
  288.     }
  289. }
  290.  
  291.  
  292. //=--------------------------------------------------------------------------=
  293. //  CShapesControl::DrawMe    
  294. //=--------------------------------------------------------------------------=
  295.  
  296. void
  297. CShapesControl::DrawMe(Rect *BoundsRect)
  298. {
  299.     Pattern            DrawPattern;
  300.     Rect            StartRect;
  301.     RGBColor        DrawColor;
  302.     PlatformRegion    DrawShape = { NULL };
  303.     DrawShape.Region = ::NewRgn();
  304.  
  305.     GetUsedArea(&DrawShape);
  306.     StartRect.top = StartRect.left = 0;
  307.     StartRect.bottom = mSize.v;
  308.     StartRect.right = mSize.h;
  309.     ::MapRgn(DrawShape.Region, &StartRect, BoundsRect);
  310.  
  311.     if (mIsPressed)
  312.         DrawColor.red = DrawColor.green = DrawColor.blue = 0x0010;
  313.     else
  314.         DrawColor.red = DrawColor.green = DrawColor.blue = 0x8000;
  315.  
  316.     ::RGBForeColor(&DrawColor);
  317.     ::StuffHex(&DrawPattern, "\pffffffffffffffff");
  318.     ::FillRgn(DrawShape.Region, &DrawPattern);
  319.     ::DisposeRgn(DrawShape.Region);
  320. }
  321.